<template>
  <el-card>
    <el-form :inline="true" class="search-form">
      <el-form-item label="用户名:">
        <el-input v-model="keyword" placeholder="请输入用户名"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="searchHandler" :disabled="keyword === ''">搜索</el-button>
        <el-button type="default" icon="Refresh" @click="reSetHandler">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <el-card class="el-card-main">
    <el-button type="primary" icon="Plus" @click="addUser">添加用户</el-button>
    <el-button :disabled="multipleSelection.length >= 1 ? false : true" type="danger" icon="Delete" @click="batchDelete">批量删除</el-button>
    <el-table :data="userArr" border @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="40" align="center" />
      <el-table-column type="index" label="序号" width="60" align="center" />
      <el-table-column prop="id" label="ID" width="120" align="center" />
      <el-table-column prop="username" label="用户名字" align="center" />
      <el-table-column prop="name" label="用户昵称" align="center" />
      <el-table-column prop="roleName" label="用户角色" align="center" />
      <el-table-column prop="createTime" label="创建时间" align="center" />
      <el-table-column prop="updateTime" label="更新时间" align="center" />
      <el-table-column label="操作" width="150" align="center">
        <template #default="{ row, index }">
          <el-button @click="assignRole(row)" type="primary" size="small" icon="User" circle></el-button>
          <el-button @click="updateUser(row)" type="warning" size="small" icon="Edit" circle></el-button>
          <el-button @click="deleteUser(row)" type="danger" size="small" icon="Delete" circle></el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      @current-change="currentPageChange"
      @size-change="pageSizeChange"
      v-model:page-size="limit"
      v-model:current-page="pageNo"
      :page-sizes="[5, 10, 20, 50, 100, 200]"
      :background="true"
      layout="prev, pager, next, jumper, ->, sizes, total"
      :total="total"
    />
  </el-card>

  <el-drawer v-model="addOrUpdateDrawer" direction="rtl" :title="userParams.id ? '更新用户' : '添加用户'">
    <el-form :inlint="false" :rules="addOrUpdateRules" :model="userParams" ref="userFormEle">
      <el-form-item prop="username" label="用户名字">
        <el-input v-model="userParams.username" placeholder="请输入用户名字"></el-input>
      </el-form-item>
      <el-form-item prop="name" label="用户昵称">
        <el-input v-model="userParams.name" placeholder="请输入用户昵称"></el-input>
      </el-form-item>
      <el-form-item prop="password" label="用户密码" v-if="!userParams.id">
        <el-input v-model="userParams.password" placeholder="请输入用户密码"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="confirm">确认</el-button>
      </div>
    </template>
  </el-drawer>

  <el-drawer v-model="assignRoleDrawer" direction="rtl" title="分配角色">
    <el-form>
      <el-form-item label="用户名字">
        <el-input disabled v-model="userParams.username"></el-input>
      </el-form-item>
      <el-form-item label="角色列表">
        <el-checkbox @change="handleCheckAllChange" v-model="checkAll" :indeterminate="isIndeterminate">全选</el-checkbox>
        <el-checkbox-group v-model="userRole" @change="handleCheckedRolesChange">
          <el-checkbox v-for="item in allRoleArr" :key="item.id" :label="item.roleName" :value="item.id"></el-checkbox>
        </el-checkbox-group>
      </el-form-item>
    </el-form>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="cancelAssignRole">取消</el-button>
        <el-button type="primary" @click="confirmAssignRole">确认</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { AllRole, AllRoleResponseData, SetRoleData, User, UserResponseData } from '@/api/acl/user/types';
import { CheckboxValueType, ElMessageBox } from 'element-plus';

// 当前页码
const pageNo = ref<number>(1);
// 当前页数据数
const limit = ref<number>(5);
// 总数据条数
const total = ref<number>(0);
// 添加用户表单元素
const userFormEle = ref();
// 用户列表
const userArr = ref<User[]>([]);
// 用户角色列表
const userRole = ref<number[]>([]);
// 所有的角色列表
const allRoleArr = ref<AllRole>([]);
// 是否全选
const checkAll = ref<boolean>(false);
// 全选状态是否确定
const isIndeterminate = ref<boolean>(true);
// 显示添加抽屉
const addOrUpdateDrawer = ref<boolean>(false);
// 显示分配角色抽屉
const assignRoleDrawer = ref<boolean>(false);
// 添加用户参数
const userParams = reactive<User>({
  name: '',
  username: '',
  password: '',
});
// 多选要删除的用户
const multipleSelection = ref<User[]>([]);
// 当前登录用户
const localUser = useUserStore();
// 搜索关键字
const keyword = ref<string>('');
//全局设置仓库
const setting = useLayoutSettingStore();

onMounted(() => {
  getUsers();
});

// 加载数据
const getUsers = async (pager = 1) => {
  pageNo.value = pager;
  const result: UserResponseData = await reqGetUsers(pageNo.value, limit.value, keyword.value);
  if (result.code === 200) {
    limit.value = result.data.size;
    total.value = result.data.total;
    userArr.value = result.data.records;
  }
};
// 搜索
const searchHandler = () => {
  getUsers();
  keyword.value = '';
};
// 重置
const reSetHandler = () => {
  setting.refresh = !setting.refresh;
};
// 页码改变
const currentPageChange = () => {
  getUsers(pageNo.value);
};
// 页面数据数改变
const pageSizeChange = () => {
  getUsers();
};

// 添加用户
const addUser = () => {
  addOrUpdateDrawer.value = true;
  //清空收集的数据
  Object.assign(userParams, {
    id: 0,
    name: '',
    username: '',
    password: '',
  });
  //清空校验消息
  nextTick(() => {
    userFormEle.value.clearValidate(['name', 'username', 'password']);
  });
};
// 更新用户
const updateUser = (row: User) => {
  addOrUpdateDrawer.value = true;
  //合并收集的数据
  Object.assign(userParams, row);
  //清空校验消息
  nextTick(() => {
    userFormEle.value.clearValidate(['name', 'username', 'password']);
  });
};
// 确认添加或者更新
const confirm = async () => {
  // 提交之前验证表单项
  await userFormEle.value.validate();

  const result: any = await reqAddOrUpdateUser(userParams);
  if (result.code === 200) {
    getUsers(userParams.id ? pageNo.value : 1);
    ElMessage.success(userParams.id ? '更新用户成功' : '添加用户成功');
    if (userParams.id === localUser.id) {
      //如果修改的是当前登录的账号则浏览器自动刷新一下
      window.location.reload();
    }
    addOrUpdateDrawer.value = false;
  } else {
    ElMessage.error(userParams.id ? '更新用户失败' : '添加用户失败');
  }
};
// 取消添加或者更新
const cancel = () => {
  addOrUpdateDrawer.value = false;
};
// 批量删除用户
const batchDelete = () => {
  const idList: number[] = [];
  let nameList: string = '';

  for (let i = 0; i < multipleSelection.value.length; i++) {
    if (multipleSelection.value[i].id) {
      idList.push(multipleSelection.value[i].id as number);
      nameList = nameList + `\n${multipleSelection.value[i].username as string}\n`;
    }
  }
  if (idList.length === 0) return;

  ElMessageBox.confirm(`确定要批量删除【${nameList}】这些用户吗？`, {
    title: '提示',
  })
    .then(async () => {
      const result: any = await reqBatchDeleteUser(idList);
      if (result.code === 200) {
        ElMessage.success('批量删除用户成功');
        getUsers(userArr.value.length >= 1 ? pageNo.value : pageNo.value - 1);
      } else {
        ElMessage.error('批量删除用户失败');
      }
    })
    .catch(() => {
      ElMessage.success('已取消批量删除');
    });
};
// 选择项列表发送改变
const handleSelectionChange = (val: User[]) => {
  multipleSelection.value = val;
};
// 删除用户
const deleteUser = (row: User) => {
  ElMessageBox.confirm(`确定要删除【${row.username}】这个用户吗？`, {
    title: '提示',
  })
    .then(async () => {
      const result: any = await reqDeleteUser(row.id as number);
      if (result.code === 200) {
        ElMessage.success('删除用户成功');
        getUsers(userArr.value.length >= 1 ? pageNo.value : pageNo.value - 1);
      } else {
        ElMessage.error('删除用户失败');
      }
    })
    .catch(() => {
      ElMessage.success('已取消删除');
    });
};
// 分配角色
const assignRole = (row: User) => {
  Object.assign(userParams, row);
  getRoles();
};
// 取消分配角色
const cancelAssignRole = () => {
  assignRoleDrawer.value = false;
};
// 确认分配角色
const confirmAssignRole = async () => {
  const assignRoleParams: SetRoleData = {
    userId: userParams.id as number,
    roleIdList: userRole.value,
  };
  const result = await reqAssignRole(assignRoleParams);
  if (result.code === 200) {
    ElMessage.success('分配角色成功');
    getUsers(pageNo.value);
    assignRoleDrawer.value = false;
  } else {
    ElMessage.error('分配角色失败');
  }
};
// 判断分配角色全选框状态是否确定
const indeterminate = () => {
  if (userRole.value.length === 0 || userRole.value.length === allRoleArr.value.length) {
    isIndeterminate.value = false;
  } else if (userRole.value.length !== 0 || userRole.value.length !== allRoleArr.value.length) {
    isIndeterminate.value = true;
  }
};
// 获得用户拥有的角色信息和所有的可分配的角色信息
const getRoles = async () => {
  const result: AllRoleResponseData = await reqGetRoles(userParams.id as number);
  if (result.code === 200) {
    allRoleArr.value = result.data.allRolesList;
    userRole.value = result.data.assignRoles.map((item) => item.id as number);
    indeterminate();
    assignRoleDrawer.value = true;
  }
};
// 选择全部角色触发
const handleCheckAllChange = (val: CheckboxValueType) => {
  userRole.value = (val as boolean) ? allRoleArr.value.map((item) => item.id as number) : [];
  isIndeterminate.value = false;
};
// 选择某个角色触发
const handleCheckedRolesChange = (value: CheckboxValueType[]) => {
  checkAll.value = value.length === allRoleArr.value.length;
  isIndeterminate.value = value.length !== allRoleArr.value.length && value.length !== 0;
};
// 自定义校验用户名称
const validatorName = (rule: any, value: any, callBack: any) => {
  if (value === '') {
    callBack(new Error('用户昵称不能为空'));
  } else if (value.trim().length >= 5) {
    callBack();
  } else {
    callBack(new Error('用户昵称长度大于等于五位'));
  }
};
// 自定义校验用户名字
const validatorUserName = (rule: any, value: any, callBack: any) => {
  if (value === '') {
    callBack(new Error('用户名字不能为空'));
  } else if (value.trim().length >= 5) {
    callBack();
  } else {
    callBack(new Error('用户名字长度大于等于五位'));
  }
};
// 自定义校验用户密码
const validatorPassword = (rule: any, value: any, callBack: any) => {
  if (value === '') {
    callBack(new Error('用户密码不能为空'));
  } else if (value.trim().length >= 6) {
    callBack();
  } else {
    callBack(new Error('用户密码长度大于等于六位'));
  }
};
// 自定义校验规则
const addOrUpdateRules = reactive({
  name: [
    {
      required: true,
      trigger: 'blur',
      validator: validatorName,
    },
  ],
  username: [
    {
      required: true,
      trigger: 'blur',
      validator: validatorUserName,
    },
  ],
  password: [
    {
      required: true,
      trigger: 'blur',
      validator: validatorPassword,
    },
    {
      trigger: 'blur',
      pattern: /^[a-zA-Z]+[a-zA-Z0-9_*]*$/,
      message: '密码必须是字母开头，可以包含数字、*和_',
    },
  ],
});
</script>

<style lang="scss" scoped>
.search-form {
  display: flex;
  justify-content: space-between;
  flex-wrap: nowrap;
  .el-form-item {
    margin: 0;
  }
}
.el-card-main {
  margin-top: 10px;

  .el-table {
    margin: 10px 0;
    height: calc(100vh - $base-tabbar-height - 230px);
  }
}
</style>
